package chapter4_对象组合.线程安全性委托;

import annotation.GuardedBy;
import annotation.ThreadSafe;

import java.util.Collections;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * 委托方式实现线程安全
 */
@ThreadSafe
public class PublishingVehicleTracker {
    private final ConcurrentMap<String, SafePoint> locations;
    private final Map<String, SafePoint> unmodifiableMap;

    public PublishingVehicleTracker(Map<String, SafePoint> points) {
        this.locations = new ConcurrentHashMap<>(points); // ConcurrentHashMap底层为每一个元素创建一个Node节点
        this.unmodifiableMap = Collections.unmodifiableMap(locations);
    }

    // 返回不可变map，不能增加删除；但是里面的SafePoint对象是可以修改的
    public Map<String, SafePoint> getLocations() {
        return unmodifiableMap;
    }

    public SafePoint getLocation(String id) {
        return locations.get(id);
    }

    public void setLocation(String id, int x, int y) {
        //因Point是不可变对象，此处需要进行替换操作
        if (locations.replace(id, new SafePoint(x, y)) == null) {
            throw new IllegalArgumentException("invalid vehicle name:" + id);
        }
    }
}

/**
 * 线程安全且可变对象
 */
@ThreadSafe
class SafePoint {
    @GuardedBy("this")
    private int x, y;

    private SafePoint(int[] a) {
        this(a[0], a[1]);
    }

    public SafePoint(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public synchronized int[] get() {
        return new int[]{x, y};
    }

    public synchronized void set(int x, int y) {
        this.x = x;
        this.y = y;
    }
}
